{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from keras.models import Sequential, load_model\n",
    "from keras.layers import Dropout, Flatten, Conv2D, MaxPooling2D, Dense, Activation\n",
    "from keras.utils import np_utils\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from keras.callbacks import TensorBoard\n",
    "import itertools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# all images will be converted to this size\n",
    "ROWS = 256\n",
    "COLS = 256\n",
    "CHANNELS = 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 5994 images belonging to 200 classes.\n",
      "Found 5794 images belonging to 200 classes.\n"
     ]
    }
   ],
   "source": [
    "train_image_generator = ImageDataGenerator(horizontal_flip=True, rescale=1./255, rotation_range=45)\n",
    "test_image_generator = ImageDataGenerator(horizontal_flip=False, rescale=1./255, rotation_range=0)\n",
    "\n",
    "train_generator = train_image_generator.flow_from_directory('train', target_size=(ROWS, COLS), class_mode='categorical')\n",
    "test_generator = test_image_generator.flow_from_directory('test', target_size=(ROWS, COLS), class_mode='categorical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_19 (Conv2D)           (None, 254, 254, 64)      1792      \n",
      "_________________________________________________________________\n",
      "activation_28 (Activation)   (None, 254, 254, 64)      0         \n",
      "_________________________________________________________________\n",
      "conv2d_20 (Conv2D)           (None, 252, 252, 64)      36928     \n",
      "_________________________________________________________________\n",
      "activation_29 (Activation)   (None, 252, 252, 64)      0         \n",
      "_________________________________________________________________\n",
      "max_pooling2d_10 (MaxPooling (None, 63, 63, 64)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_21 (Conv2D)           (None, 61, 61, 64)        36928     \n",
      "_________________________________________________________________\n",
      "activation_30 (Activation)   (None, 61, 61, 64)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_22 (Conv2D)           (None, 59, 59, 64)        36928     \n",
      "_________________________________________________________________\n",
      "activation_31 (Activation)   (None, 59, 59, 64)        0         \n",
      "_________________________________________________________________\n",
      "max_pooling2d_11 (MaxPooling (None, 14, 14, 64)        0         \n",
      "_________________________________________________________________\n",
      "flatten_5 (Flatten)          (None, 12544)             0         \n",
      "_________________________________________________________________\n",
      "dropout_8 (Dropout)          (None, 12544)             0         \n",
      "_________________________________________________________________\n",
      "dense_9 (Dense)              (None, 400)               5018000   \n",
      "_________________________________________________________________\n",
      "activation_32 (Activation)   (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dropout_9 (Dropout)          (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense_10 (Dense)             (None, 200)               80200     \n",
      "_________________________________________________________________\n",
      "activation_33 (Activation)   (None, 200)               0         \n",
      "=================================================================\n",
      "Total params: 5,210,776\n",
      "Trainable params: 5,210,776\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "train_generator.reset()\n",
    "test_generator.reset()\n",
    "\n",
    "model = Sequential()\n",
    "model.add(Conv2D(64, (3,3), input_shape=(ROWS, COLS, CHANNELS)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3,3)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPooling2D(pool_size=(4,4)))\n",
    "model.add(Conv2D(64, (3,3)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3,3)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(MaxPooling2D(pool_size=(4,4)))\n",
    "model.add(Flatten())\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Dense(400))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.5))\n",
    "model.add(Dense(200))\n",
    "model.add(Activation('softmax'))\n",
    "\n",
    "model.compile(loss='categorical_crossentropy', optimizer='adamax', metrics=['accuracy'])\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      " - 434s - loss: 4.4682 - acc: 0.0687\n",
      "Epoch 2/10\n",
      " - 440s - loss: 4.1851 - acc: 0.0919\n",
      "Epoch 3/10\n",
      " - 443s - loss: 3.9278 - acc: 0.1270\n",
      "Epoch 4/10\n",
      " - 428s - loss: 3.6948 - acc: 0.1615\n",
      "Epoch 5/10\n",
      " - 437s - loss: 3.4944 - acc: 0.1935\n",
      "Epoch 6/10\n",
      " - 439s - loss: 3.3103 - acc: 0.2196\n",
      "Epoch 7/10\n",
      " - 438s - loss: 3.1253 - acc: 0.2492\n",
      "Epoch 8/10\n",
      " - 443s - loss: 2.9927 - acc: 0.2757\n",
      "Epoch 9/10\n",
      " - 431s - loss: 2.8474 - acc: 0.2998\n",
      "Epoch 10/10\n",
      " - 430s - loss: 2.7354 - acc: 0.3271\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7fe46c531be0>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tensorboard = TensorBoard(log_dir='./logs/custom')\n",
    "\n",
    "model.fit_generator(train_generator, steps_per_epoch=512, epochs=10, callbacks=[tensorboard], verbose=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3.3455331521880121, 0.22266875981161696]\n"
     ]
    }
   ],
   "source": [
    "print(model.evaluate_generator(test_generator, steps=1000))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
